package com.bringway.global.util.viewResover;

import java.util.Locale;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.AbstractView;
import org.springframework.web.servlet.view.InternalResourceView;
import org.springframework.web.servlet.view.RedirectView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

public class MultiViewResover extends ApplicationObjectSupport implements ViewResolver {
	
	Logger logger = Logger.getLogger(this.getClass().getName());
	
	public static final String REDIRECT_URL_PREFIX = "redirect:";
	
	public static final String FORWARD_URL_PREFIX = "forward:";

	private Map<String, ViewResolver> resolvers;
	
	@Override
	public View resolveViewName(String viewName, Locale locale) throws Exception {
		logger.info("视图请求信息：[viewName： " + viewName + "， locale： " + locale + "]");
		if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
			String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
			RedirectView view = new RedirectView(redirectUrl, true, true);
			return applyLifecycleMethods(viewName, view);
		}
		// Check for special "forward:" prefix.
		if (viewName.startsWith(FORWARD_URL_PREFIX)) {
			String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length());
			return new InternalResourceView(forwardUrl);
		}
		
		int n = viewName.lastIndexOf("."); // 获取
											// viewName(modelAndView中的名字)看其有没有下划线
		String suffix = "";

		// 没有默认使用“jsp“方式 解析,有的话截取下划线后面的字符串 这里一般是jsp,ftl,vm与配置文件中的<entry
		// key="ftl">的key匹配
		if (n == (-1)) {
			suffix = "jsp";
		}
		else {
			suffix = viewName.substring(n + 1);
			// 取下划线前面的部分 那时真正的资源名.比如我们要使用hello.jsp 那viewName就应该是hello_jsp
			viewName = viewName.substring(0, n);
		}

		// 根据下划线后面的字符串去获取托管的视图解析类对象
		ViewResolver resolver = resolvers.get(suffix);

		if (resolver != null) {
			return resolver.resolveViewName(viewName, locale);
		}
		else {
			return null;
		}
	}

	private View applyLifecycleMethods(String viewName, AbstractView view) {
		return (View) getApplicationContext().getAutowireCapableBeanFactory().initializeBean(view, viewName);
	}
	
	public Map<String, ViewResolver> getResolvers() {
		return resolvers;
	}

	public void setResolvers(Map<String, ViewResolver> resolvers) {
		this.resolvers = resolvers;
	}
}
